package rpg.writer.app;

import java.awt.BorderLayout;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;

import javax.swing.JFrame;

import rpg.client.player.swing.PlayerJDialog;
import rpg.engine.client.GameEngineFacade;
import rpg.engine.model.World;
import rpg.util.Close;
import rpg.writer.scripts.ScriptWarning;
import rpg.writer.scripts.impl.ScriptAnalyzer;

public class WriterJFrame extends JFrame {
	/**
     * 
     */
	private static final long serialVersionUID = -5619052550923032131L;

	public static void createAndShowGUI() {
		final WriterJFrame wjf = new WriterJFrame();
		wjf.setVisible(true);
	}

	private static void debug(final Object o) {
		System.out.println("WriterJFrame: " + o);
	}

	private final MenuJPanel menu = new MenuJPanel();

	private final ScriptJPanel script;
	private final ConsoleJPanel console = new ConsoleJPanel();

	private WriterJFrame() {
		super();
		script = new ScriptJPanel(this);
		createGui();
		pack();
		initialize();
	}

	private void createGui() {
		// Set Main Layout
		getContentPane().setLayout(new BorderLayout());

		getContentPane().add(menu, BorderLayout.WEST);
		getContentPane().add(script, BorderLayout.CENTER);
		getContentPane().add(console, BorderLayout.EAST);

		// Set up Listeners
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private void initialize() {
		String myScript = "";

		try {
			myScript = loadInternalScript("scripts/tutorial.txt");
		} catch (final IOException e) {
			e.printStackTrace();
		} finally {
			script.setScript(myScript);
		}
	}

	String loadInternalScript(final String internalPath) throws IOException {
		InputStream is = null;

		try {
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
			is = getClass().getClassLoader().getResourceAsStream(internalPath);
			if (is == null) {
				return "";
			}

			int available = is.available();
			byte[] bytes = new byte[available];
			while (available > 0) {
				if (available > bytes.length) {
					bytes = new byte[available];
				}
				final int readCount = is.read(bytes, 0, available);
				baos.write(bytes, 0, readCount);
				available = is.available();
			}

			return new String(baos.toByteArray());
		} finally {
			Close.andReturnException(is);
		}
	}

	public void play(final String newScript) {
		final String[] lines = newScript.split("\n");

		final ScriptAnalyzer analyzer = new ScriptAnalyzer("S1",
				Arrays.asList(lines));

		final World world = analyzer.create();
		final Collection<ScriptWarning> warnings = analyzer.getWarnings();
		debug(warnings);

		final GameEngineFacade facade = new GameEngineFacade(world);

		PlayerJDialog.launch(facade);
		// ClientJDialog.startGame(facade);
	}
}
